package com.sta.oldman;

import com.sta.oldman.coder.TcpHandler;
import com.sta.oldman.coder.TcpMsg;
import com.sta.oldman.coder.TcpMsgDecoder;
import com.sta.oldman.coder.TcpMsgEncoder;
import com.sta.oldman.constants.MsgContains;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;

import java.util.concurrent.TimeUnit;

public class Client {
    private static final String HOST = "localhost";
    private static final int PORT = 8082;

    public static void main(String[] args) throws InterruptedException {
        NioEventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<Channel>() {
                        @Override
                        protected void initChannel(Channel ch) throws Exception {
                            ByteBuf delimiter = Unpooled.copiedBuffer(MsgContains.DEFAULT_DECODE_CHAR.getBytes());
                            ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024 * 8, delimiter));
                            ch.pipeline().addLast(new TcpMsgDecoder());
                            ch.pipeline().addLast(new TcpMsgEncoder());
                            ch.pipeline().addLast(new TcpHandler());
                        }
                    });
            // 连接到服务器
            ChannelFuture future = bootstrap.connect(HOST, PORT).sync();
            Channel channel = future.channel();
            String msg="53 59 80 03 01 01 31 54 43 53 59 80 04 02 0B 3D 54 43 53 59 80 03 01 01 31 54 43 53 59 80 05 06 80 05 09 C5 54 43 53 59 80 03 01 01 31 54 43 53 59 80 04 02 0B 3D 54 43 53 59 80 03 01 01 31 54 43 53 59 80 05 06 80 05 09 C5 54 43 53 59 80 03 01 01 31 54 43 53 59 80 04 02 0B 3D 54 43 53 59 80 03 01 01 31 54 43 53 59 80 05 06 80 05 09 C5 54 43 53 59 80 03 01 01 31 54 43 53 59 80 04 02 0B 3D 54 43 53 59 80 03 01 01 31 54 43 53 59 80 05 06 80 05 09 C5 54 43 53 59 80 03 01 01 31 54 43 53 59 80 04 02 17 49 54 43 53 59 80 03 01 01 31 54 43 53 59 80 05 06 80 13 0B D5 54 43 53 59 80 03 01 01 31 54 43 53 59 80 04 02 17 49 54 43 53 59 80 03 01 01 31 54 43 53 59 80 05 06 80 13 0B D5 54 43 53 59 80 03 01 01 31 54 43 53 59 80 04 02 17 49 54 43 53 59 80 03 01 01 31 54 43 53 59 80 05 06 80 13 0B D5 54 43 53 59 80 03 01 01 31 54 43 53 59 80 04 02 23 55 54 43 53 59 80 03 01 01 31 54 43 53 59 80 05 06 80 1D 13 E7 54 43 53 59 80 03 01 01 31 54 43 53 59 80 04 02 23 55 54 43 53 59 80 03 01 01 31 54 43 53 59 80 05 06 80 1D 13 E7 54 43 53 59 80 03 01 01 31 54 43 53 59 80 04 02 23 55 54 43 53 59 80 03 01 01 31 54 43 53 59 80 05 06 80 1D 13 E7 54 43 53 59 80 03 01 01 31 54 43 53 59 80 04 02 23 55 54 43 53 59 80 03 01 01 31 54 43 53 59 80 05 06 80 05 09 C5 54 43 53 59 80 03 01 01 31 54 43 53 59 80 04 02 0B 3D 54 43 53 59 80 03 01 01 31 54 43 53 59 80 05 06 80 05 09 C5 54 43 53 59 80 03 01 01 31 54 43 53 59 80 04 02 0B 3D 54 43 53 59 80 03 01 01 31 54 43 53 59 80 05 06 80 05 09 C5 54 43";
            String[] bytes = msg.split(" ");
            int index = 0;

            while (index + 8 < bytes.length) { // 确保有足够的数据构成完整消息
                // 检查消息头(0x53 0x59)
                if (!bytes[index].equals("53") || !bytes[index+1].equals("59")) {
                    index++;
                    continue;
                }

                // 确保有足够的数据读取control, command, length
                if (index + 4 >= bytes.length) break;

                byte control = (byte)Integer.parseInt(bytes[index+2], 16);
                byte command = (byte)Integer.parseInt(bytes[index+3], 16);
                short len = (short)Integer.parseInt(bytes[index+4], 16);

                // 确保有足够的数据读取body和校验和、尾部
                if (index + 5 + len + 2 >= bytes.length) break;

                // 提取数据部分
                byte[] body = new byte[len];
                for (int i = 0; i < len; i++) {
                    body[i] = (byte)Integer.parseInt(bytes[index+5+i], 16);
                }

                // 计算校验和
                int sum = 0x5359; // 头部
                sum += control & 0xFF;
                sum += command & 0xFF;
                sum += len & 0xFFFF;
                for (byte b : body) {
                    sum += b & 0xFF;
                }
                sum = sum & 0xFF;
                byte checksum = (byte)sum;

                // 检查消息尾(0x54 0x43)
                if (!bytes[index+6+len].equals("54") || !bytes[index+7+len].equals("43")) {
                    index++;
                    continue;
                }

                // 创建并发送TcpMsg
                TcpMsg tcpMsg = new TcpMsg(control, command, len, body, checksum);
                channel.writeAndFlush(tcpMsg);

                // 移动到下一个消息
                index += 8 + len;

                // 添加间隔防止发送过快
                Thread.sleep(100);
            }
            channel.closeFuture().await(5, TimeUnit.SECONDS);
        } finally {
            group.shutdownGracefully();
        }
    }
}